/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.sunrise.boundary;

import com.github.dvdme.ForecastIOLib.FIODaily;
import com.github.dvdme.ForecastIOLib.FIODataPoint;
import com.github.dvdme.ForecastIOLib.ForecastIO;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.Stateless;

/**
 *
 * @author frank
 */
@Stateless
public class WeatherManager {

    private ForecastIO fio;
    
    SimpleDateFormat dateFormatterForecastIO;
    
    @PostConstruct
    private void init() {
        fio = new ForecastIO("d41834f2726a2c40db711eab725915bd");
        fio.setUnits(ForecastIO.UNITS_SI);
        fio.setExcludeURL("hourly,minutely");
        
        dateFormatterForecastIO = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
    }

    public List<FIODataPoint> getWeatherForLocation(String lat, String lng) {
        List<FIODataPoint> days = new ArrayList<>();

        try {
            if(fio != null && lat != null && lng != null && !lat.isEmpty() && !lng.isEmpty()) {
                boolean res = fio.getForecast(lat, lng);
                if(res) {
                    FIODaily daily = new FIODaily(fio);

                    for (int i = 0; i < daily.days(); i++) {
                        FIODataPoint day = daily.getDay(i);
                        days.add(day);
                    }
                }
            }
        } catch (Exception ex) {
        
        }
        
        return days;
    }
    
    public Date dateStringForDay(FIODataPoint day) {
        Date dayDate = null;
        
        try {
            dayDate = dateFormatterForecastIO.parse(day.time());
        } catch (ParseException ex) {

        }

        return dayDate;
    }
    
    public String iconForDay(FIODataPoint day) {
        String result = "";
        
        if(day != null && day.icon() != null)
            result = day.icon().replace("\"", "");
        
        return result;
    }        
              
    public boolean badWeatherForLocationAndDate(List<FIODataPoint> dailyForecasts, Date date) {   
        
        boolean result = false;
        
        try {
            if(date != null) {
                DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
                String dateString = dateFormat.format(date);       

                for (FIODataPoint dailyForecast : dailyForecasts) {
                    Date dayDate = dateStringForDay(dailyForecast);              
                    String dayDateString = dateFormat.format(dayDate);
                    String iconString = iconForDay(dailyForecast);

                    if(dayDateString != null && dayDateString.equals(dateString)) {
                        if(!iconString.equals("clear-day")) {
                            result = true;
                        }    

                        break;
                    }
                }
            }
        } catch (Exception ex) {
            
        }
    
        return result;
    }
    
    public FIODataPoint findSuggestedDataPoint(List<FIODataPoint> dailyForecast, Date date) {
        
        FIODataPoint resultPost = null;
        FIODataPoint resultAnte = null;
        
        try {
            if(date != null) {

                Date today = new Date();

                for (FIODataPoint tmpDailyForecast : dailyForecast) {
                    Date dayDate = dateStringForDay(tmpDailyForecast);              
                    String iconString = iconForDay(tmpDailyForecast);

                    if(dayDate != null && dayDate.after(today) && iconString.equals("clear-day")) { 

                        long diffDateDayDate = dateDiffSeconds(date, dayDate);

                        long diffDateResultPost;                  

                        long diffDayDateDate = dateDiffSeconds(dayDate, date);

                        long diffResultAnteDate;                       

                        if(dayDate.after(date)){
                            if(resultPost == null) {
                                resultPost = tmpDailyForecast;
                            } else {
                                diffDateResultPost = dateDiffSeconds(date, dateStringForDay(resultPost));

                                if (diffDateDayDate < diffDateResultPost) {
                                    resultPost = tmpDailyForecast;
                                }
                            }
                        } else if(!dayDate.after(date) ) {
                            if(resultAnte == null) {
                                resultAnte = tmpDailyForecast;
                            } else {
                                diffResultAnteDate = dateDiffSeconds(dateStringForDay(resultAnte), date);

                                if(diffDayDateDate < diffResultAnteDate) {
                                    resultAnte = tmpDailyForecast;
                                }
                            }   
                        }     
                    }    
                }
            }
        } catch (Exception ex) {
        
        }
        
        return resultPost != null ? resultPost : resultAnte;
    }
    
    public long dateDiffHours(Date lowerDate, Date higherDate) {
        if (higherDate != null && lowerDate != null) {
            long higherTime = higherDate.getTime();
            long lowerTime = lowerDate.getTime();
            long diffTime = higherTime - lowerTime;
            return diffTime / (1000 * 60 * 60);
        } else {
            return Long.MIN_VALUE;
        }
    }
    
    public long dateDiffSeconds(Date lowerDate, Date higherDate) {
        if (higherDate != null && lowerDate != null) {
            long higherTime = higherDate.getTime();
            long lowerTime = lowerDate.getTime();
            long diffTime = higherTime - lowerTime;
            return diffTime / (1000);
        } else {
            return Long.MIN_VALUE;
        }
    }
}
